package com.plian.system.service.yth.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.plian.Tools.CollectionUtil;
import com.plian.system.constant.im.InvestmentConstant;
import com.plian.system.entity.im.FundProjectAmountDetail;
import com.plian.system.entity.yth.Fund;
import com.plian.system.entity.yth.FundGpLp;
import com.plian.system.mapper.yth.FundGpLpMapper;
import com.plian.system.mapper.yth.FundMapper;
import com.plian.system.service.im.IFundProjectAmountDetailService;
import com.plian.system.service.yth.IFundService;
import com.plian.system.vo.im.FundProjectInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Slf4j
@Service
public class FundServiceImpl extends ServiceImpl<FundMapper, Fund> implements IFundService {

    private final String YTH_DATASOURCE_TYPE = "3";

    @Autowired
    private FundGpLpMapper fundGpLpMapper;

    @Autowired
    private IFundProjectAmountDetailService fundProjectAmountDetailService;

    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
//    @DS("slave_1")
    @Override
    public List<FundProjectInfoVO> getAllProject(Date startTime, Date endTime) {
        List<FundProjectInfoVO> fundProjectInfoVOS = new ArrayList<>();

        List<Fund> funds = list(new LambdaQueryWrapper<Fund>()
                .gt(Optional.ofNullable(startTime).isPresent(),Fund::getCreateTime,startTime)
                .le(Optional.ofNullable(endTime).isPresent(),Fund::getCreateTime,endTime)
        );
        if (CollectionUtil.isNotEmpty(funds)){
            fundProjectInfoVOS = conversion(funds);
        }
        return fundProjectInfoVOS;
    }
//    @DS("slave_1")
private List<FundProjectInfoVO> conversion(List<Fund> funds){
        List<FundProjectInfoVO> fundProjectInfoVOS= new ArrayList<>();
        ZoneId zone = ZoneId.systemDefault();
        for (Fund fund:funds){
            FundProjectInfoVO fundProjectInfoVO = new FundProjectInfoVO();
            List<FundGpLp> fundGpLpList = fundGpLpMapper.selectList(new LambdaQueryWrapper<FundGpLp>()
                    .eq(FundGpLp:: getFundId, fund.getId()));
            fundProjectInfoVO.setFundName(fund.getNm());
            Optional.ofNullable(fund.getDeptId()).ifPresent(m ->{
                fundProjectInfoVO.setCompanyId(m.toString());
            });
            fundProjectInfoVO.setInvestmentSubject(fund.getDeptNm());
            Optional.ofNullable(fund.getEstablishTime()).ifPresent( m ->{
                fundProjectInfoVO.setStartTime(Date.from(m.atZone(zone).toInstant()));
            });
            Optional.ofNullable(fund.getEndTime()).ifPresent((m ->{
                fundProjectInfoVO.setEndTime(Date.from(m.atZone(zone).toInstant()));
            }));
            List<FundProjectAmountDetail> details1 = new ArrayList<>();
            List<FundProjectAmountDetail> details2 = new ArrayList<>();
            int i  = 0, j = 0;
            fundGpLpList.stream().forEach(m->{
                FundProjectAmountDetail detail = new FundProjectAmountDetail();
                Optional.ofNullable(m.getType()).ifPresent(type ->{
                    if(m.getType() == 1){
                        detail.setOrderNumber(i + 1);
                        detail.setCompanyName(m.getDeptNm());
                        detail.setAmountType(InvestmentConstant.GP_AMOUNT_DETAIL_TYPE);
                        detail.setAmount(m.getAmt());
                        detail.setFundProjectId(m.getId());
                        details1.add(detail);
                    }else if(m.getType() == 2){
                        detail.setOrderNumber(j + 1);
                        detail.setCompanyName(m.getDeptNm());
                        detail.setAmountType(InvestmentConstant.LP_AMOUNT_DETAIL_TYPE);
                        detail.setAmount(m.getAmt());
                        detail.setFundProjectId(m.getId());
                        details2.add(detail);
                    }
                });
            });
            fundProjectInfoVO.setGpDetailList(details1);
            fundProjectInfoVO.setLpDetailList(details2);
            fundProjectInfoVO.setGp(fund.getGpAmt());
            fundProjectInfoVO.setLp(fund.getLpAmt());
            fundProjectInfoVO.setFundScale(fund.getFundSize());
            fundProjectInfoVO.setContributedCapital(fund.getPaidAmt());
            fundProjectInfoVO.setCompanyContributedCapital(fund.getSelfCompSubscribedAmt());
            fundProjectInfoVO.setHasContributedCapital(fund.getSelfCompPaidAmt());
            fundProjectInfoVO.setCreateCompanyId(fund.getCreateDept().toString());
            fundProjectInfoVO.setCreateUser(fund.getCreateUser().toString());
            switch (fund.getManageType()){
                case 1:
                    fundProjectInfoVO.setManageMode("131001");
                    break;
                case 2:
                    fundProjectInfoVO.setManageMode("131002");
                    break;
                default:
                    break;
            }
            switch (fund.getFundType()){
                case 1:
                    fundProjectInfoVO.setFundType("132001");
                    break;
                case 2:
                    fundProjectInfoVO.setFundType("132002");
                    break;
                case 3:
                    fundProjectInfoVO.setFundType("132003");
                    break;
                case 4:
                    fundProjectInfoVO.setFundType("132004");
                    break;
                default:
                    break;
            }
            switch (fund.getOrganForm()){
                case 1:
                    fundProjectInfoVO.setOrganizationForm("133001");
                    break;
                case 2:
                    fundProjectInfoVO.setOrganizationForm("133002");
                    break;
                case 3:
                    fundProjectInfoVO.setOrganizationForm("133003");
                    break;
                default:
                    break;
            }
            switch (fund.getFundStatus()){
                case 1:
                    fundProjectInfoVO.setFundStatus("134001");
                    break;
                case 2:
                    fundProjectInfoVO.setFundStatus("134002");
                    break;
                case 3:
                    fundProjectInfoVO.setFundStatus("134003");
                    break;
                case 4:
                    fundProjectInfoVO.setFundStatus("134004");
                    break;
                case 5:
                    fundProjectInfoVO.setFundStatus("134005");
                    break;
                default:
                    break;
            }
            fundProjectInfoVO.setInternalYieldRate(fund.getInterEarnRate());
            switch (fund.getManagerType()){
                case 1:
                    fundProjectInfoVO.setManagerType("135001");
                    break;
                case 2:
                    fundProjectInfoVO.setManagerType("135002");
                    break;
                case 3:
                    fundProjectInfoVO.setManagerType("135003");
                    break;
                case 4:
                    fundProjectInfoVO.setManagerType("135004");
                    break;
                default:
                    break;
            }
            fundProjectInfoVO.setSubscribedCapital(fund.getSubscribedAmt());
            fundProjectInfoVO.setYearContributedCapital(fund.getNowYearPaidAmt());
            fundProjectInfoVO.setCompanyYearContributedCapital(fund.getSelfCompNowYearPaidAmt());
            fundProjectInfoVO.setAffiliatedOrgFullName(fund.getGroupFullNm());
            switch (fund.getFundNature()){
                case 1:
                    fundProjectInfoVO.setFundNature("137001");
                    break;
                case 2:
                    fundProjectInfoVO.setFundNature("137002");
                    break;
                case 3:
                    fundProjectInfoVO.setFundNature("137003");
                    break;
                default:
                    break;
            }
            fundProjectInfoVO.setDataSource(YTH_DATASOURCE_TYPE);
            fundProjectInfoVO.setDataSourceId(fund.getId().toString());
            fundProjectInfoVOS.add(fundProjectInfoVO);

        }
        return fundProjectInfoVOS;
    }

}
